home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / nasm095s.zip / RDOFF / RDFLOAD.C < prev    next >
C/C++ Source or Header  |  1997-07-27  |  4KB  |  174 lines

  1. /* rdfload.c    RDOFF Object File loader library
  2.  *
  3.  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  4.  * Julian Hall. All rights reserved. The software is
  5.  * redistributable under the licence given in the file "Licence"
  6.  * distributed in the NASM archive.
  7.  *
  8.  * Permission to use this file in your own projects is granted, as long
  9.  * as acknowledgement is given in an appropriate manner to its authors,
  10.  * with instructions of how to obtain a copy via ftp.
  11.  */
  12.  
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15.  
  16. #include "rdfload.h"
  17. #include "symtab.h"
  18. #include "rdoff.h"
  19. #include "collectn.h"
  20.  
  21. extern int rdf_errno;
  22.  
  23. rdfmodule * rdfload(const char *filename)
  24. {
  25.     rdfmodule     * f = malloc(sizeof(rdfmodule));
  26.     long     bsslength = 0;
  27.     char    * hdr;
  28.     rdfheaderrec *r;
  29.  
  30.     if (f == NULL) 
  31.     {
  32.     rdf_errno = 6;        /* out of memory */
  33.     return NULL;
  34.     }
  35.  
  36.     f->symtab = symtabNew();
  37.     if (!f->symtab)
  38.     {
  39.     free(f);
  40.     rdf_errno = 6;
  41.     return NULL;
  42.     }
  43.  
  44.     /* open the file */
  45.     if ( rdfopen( &(f->f), filename ) ) {
  46.     free(f);
  47.     return NULL;
  48.     }
  49.  
  50.     /* read in text and data segments, and header */
  51.     
  52.     f->t = malloc (f->f.code_len);
  53.     f->d = malloc (f->f.data_len); /* BSS seg allocated later */
  54.     hdr = malloc (f->f.header_len);
  55.  
  56.     if (! f->t || ! f->d || !hdr) {
  57.     rdf_errno = 6;
  58.     rdfclose(&f->f);
  59.     if (f->t) free(f->t);
  60.     if (f->d) free(f->d);
  61.     free(f);
  62.     return NULL;
  63.     }
  64.  
  65.     if ( rdfloadseg (&f->f,RDOFF_HEADER,hdr) ||
  66.      rdfloadseg (&f->f,RDOFF_CODE,f->t) ||
  67.      rdfloadseg (&f->f,RDOFF_DATA,f->d) )
  68.     {
  69.     rdfclose(&f->f);
  70.     free(f->t);
  71.     free(f->d);
  72.     free(f);
  73.     free(hdr);
  74.     return NULL;
  75.     }
  76.  
  77.     rdfclose(&f->f);
  78.  
  79.     /* Allocate BSS segment; step through header and count BSS records */
  80.  
  81.     while ( ( r = rdfgetheaderrec (&f->f) ) )
  82.     {
  83.     if (r->type == 5)
  84.         bsslength += r->b.amount;
  85.     }
  86.  
  87.     f->b = malloc ( bsslength );
  88.     if (! f->b )
  89.     {
  90.     free(f->t);
  91.     free(f->d);
  92.     free(f);
  93.     free(hdr);
  94.     rdf_errno = 6;
  95.     return NULL;
  96.     }
  97.  
  98.     rdfheaderrewind (&f->f);
  99.  
  100.     f->textrel = (long)f->t;
  101.     f->datarel = (long)f->d;
  102.     f->bssrel  = (long)f->b;
  103.  
  104.     return f;
  105. }
  106.  
  107. int rdf_relocate(rdfmodule * m)
  108. {
  109.     rdfheaderrec    * r;
  110.     Collection        imports;    
  111.     symtabEnt        e;
  112.     long        rel;
  113.     unsigned char    * seg;
  114.     
  115.     rdfheaderrewind ( & m->f );
  116.     collection_init(&imports);
  117.  
  118.     while ( (r = rdfgetheaderrec ( & m->f ) ) )
  119.     {
  120.     switch (r->type)
  121.     {
  122.     case 1:        /* Relocation record */
  123.  
  124.         /* calculate relocation factor */
  125.  
  126.         if (r->r.refseg == 0) rel = m->textrel;
  127.         else if (r->r.refseg == 1) rel = m->datarel;
  128.         else if (r->r.refseg == 2) rel = m->bssrel;
  129.         else
  130.         /* We currently do not support load-time linkage.
  131.            This should be added some time soon... */
  132.  
  133.         return 1;    /* return error code */
  134.  
  135.         if ((r->r.segment & 63) == 0) seg = m->t;
  136.         else if ((r->r.segment & 63) == 1) seg = m->d;
  137.         else
  138.         return 1;
  139.  
  140.         /* it doesn't matter in this case that the code is non-portable,
  141.            as the entire concept of executing a module like this is
  142.            non-portable */
  143.         switch(r->r.length) {
  144.         case 1:
  145.         seg[r->r.offset] += (char) rel;
  146.         break;
  147.         case 2:
  148.         *(int16 *)(seg + r->r.offset) += (int16) rel;
  149.         break;
  150.         case 4:
  151.         *(long *)(seg + r->r.offset) += rel;
  152.         break;
  153.         }
  154.         break;
  155.  
  156.     case 3:            /* export record - add to symtab */
  157.         e.segment = r->e.segment;
  158.         e.offset = r->e.offset + 
  159.                    (e.segment == 0 ? m->textrel : /* 0 -> code */
  160.             e.segment == 1 ? m->datarel : /* 1 -> data */
  161.                              m->bssrel) ; /* 2 -> bss  */
  162.         e.flags = 0;
  163.         e.name = malloc(strlen(r->e.label) + 1);
  164.         if (! e.name)
  165.         return 1;
  166.  
  167.         strcpy(e.name,r->e.label);
  168.         symtabInsert(m->symtab,&e);
  169.         break;
  170.     }
  171.     }    
  172.     return 0;
  173. }
  174.